package com.qing.test.aspect;


import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.qing.test.annotation.ResultListNotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.io.IOException;
import java.util.List;

@Slf4j
@RestControllerAdvice
public class ListNullProcessor implements ResponseBodyAdvice<Object> {

    private final ObjectMapper nullListMapper;

    public ListNullProcessor(MappingJackson2HttpMessageConverter converter) {
        // 创建专门处理空List的ObjectMapper
        this.nullListMapper = converter.getObjectMapper().copy();
        this.nullListMapper.registerModule(new SimpleModule()
                .setSerializerModifier(new ListNotNullSerializerModifier()));
    }

    // 只处理带有@ResultListNotNull注解的方法
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return returnType.hasMethodAnnotation(ResultListNotNull.class) ||
                returnType.getContainingClass().isAnnotationPresent(ResultListNotNull.class);
    }

    // 在响应前处理返回值
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (body == null) {
            return null;
        }

        try {
            // 使用自定义ObjectMapper将对象序列化为JSON字符串，然后再解析回来
            // 这样可以确保null的List字段被正确序列化为空数组[]
            String json = nullListMapper.writeValueAsString(body);
            return nullListMapper.readValue(json, body.getClass());
        } catch (Exception e) {
            log.error("处理带null的List字段时出错", e);
            return body;
        }
    }

    // 自定义序列化修饰器
    private static class ListNotNullSerializerModifier extends BeanSerializerModifier {
        @Override
        public List<BeanPropertyWriter> changeProperties(
                SerializationConfig config,
                BeanDescription beanDesc,
                List<BeanPropertyWriter> beanProperties
        ) {
            for (BeanPropertyWriter writer : beanProperties) {
                JavaType type = writer.getType();
                if (type.isCollectionLikeType() && List.class.isAssignableFrom(type.getRawClass())) {
                    writer.assignNullSerializer(NullListSerializer.INSTANCE);
                }
            }
            return beanProperties;
        }
    }

    // 空List序列化器
    private static class NullListSerializer extends JsonSerializer<Object> {
        public static final NullListSerializer INSTANCE = new NullListSerializer();

        @Override
        public void serialize(Object value, JsonGenerator gen, SerializerProvider provider)
                throws IOException {
            gen.writeStartArray();
            gen.writeEndArray();
        }
    }
}
